#include <string.h>
#include <ctype.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

#include "esp_peripherals.h"
#include "periph_sdcard.h"
#include "periph_wifi.h"
#include "periph_button.h"
#include "periph_console.h"

#include "sdcard_list.h"
#include "sdcard_scan.h"
#include "audio_sys.h"

#include "esp_wifi.h"

#include "audio_idf_version.h"

#include "app_music_play.h"

#include "app_nvs_param.h"

#include "app_console_debug.h"
static const char *TAG = "app.console";

extern esp_periph_set_handle_t set;

static esp_err_t console_demo_func(esp_periph_handle_t periph, int argc, char *argv[])
{
    ESP_LOGI(TAG, "console demo func.");
    return 0;
}

static esp_err_t cli_play(esp_periph_handle_t periph, int argc, char *argv[])
{
    ESP_LOGI(TAG, "app_audio play");
    char *str = NULL;
    int byte_pos = 0;
    if (argv[0] && argc) {
        if (argv[1]) {
            byte_pos = atoi(argv[1]);
        }
        str = argv[0];
        app_audio_play(str,  byte_pos);
        ESP_LOGI(TAG, "play index= %d, URI:%s, byte_pos:%d", -1, argv[0], byte_pos);
    }else{
        app_audio_play(NULL,  0);        
    }

    return ESP_OK;
}

static esp_err_t cli_pause(esp_periph_handle_t periph, int argc, char *argv[])
{
    app_audio_pause();
    return ESP_OK;
}

static esp_err_t cli_resume(esp_periph_handle_t periph, int argc, char *argv[])
{
    app_audio_resume();
    return ESP_OK;
}

static esp_err_t cli_stop(esp_periph_handle_t periph, int argc, char *argv[])
{
    app_audio_stop();
    return ESP_OK;
}

static esp_err_t cli_set_vol(esp_periph_handle_t periph, int argc, char *argv[])
{
    int cur_vol = 0;
    if (argc == 1) {
        cur_vol = atoi(argv[0]);
    } else {
        ESP_LOGE(TAG, "Invalid volume parameter");
        return ESP_ERR_INVALID_ARG;
    }
    app_audio_set_vol(cur_vol);

    return ESP_OK;
}

static esp_err_t cli_get_vol(esp_periph_handle_t periph, int argc, char *argv[])
{
    int vol = 0;
    app_audio_get_vol(&vol);
    ESP_LOGI(TAG, "Current volume is %d", vol);
    return ESP_OK;
}

static esp_err_t playlist_sd_scan(esp_periph_handle_t periph, int argc, char *argv[])
{
    if (argc == 1) {
        app_audio_playlist_sd_scan(argv[0]);
    } else {
        ESP_LOGE(TAG, "Please enter the can path");
        return ESP_ERR_INVALID_ARG;
    }
    return ESP_OK;
}

static esp_err_t playlist_sd_show(esp_periph_handle_t periph, int argc, char *argv[])
{
    app_audio_playlist_sd_show();
    return ESP_OK;
}

static esp_err_t playlist_sd_next(esp_periph_handle_t periph, int argc, char *argv[])
{
    int step = 0;
    if (argc == 1) {
        step = atoi(argv[0]);
    } else {
        ESP_LOGE(TAG, "Invalid next step parameter");
        return ESP_ERR_INVALID_ARG;
    }
    app_audio_playlist_sd_next(step);
    return ESP_OK;
}

static esp_err_t playlist_sd_prev(esp_periph_handle_t periph, int argc, char *argv[])
{
    int step = 0;
    if (argc == 1) {
        step = atoi(argv[0]);
    } else {
        ESP_LOGE(TAG, "Invalid previous step parameter");
        return ESP_ERR_INVALID_ARG;
    }
    app_audio_playlist_sd_prev(step);
    return ESP_OK;
}

static esp_err_t nvs_mqtt_param_set(esp_periph_handle_t periph, int argc, char *argv[])
{
    mqtt_nvs_param_t param_mqtt = NULL;
    param_mqtt = malloc(sizeof(mqtt_nvs_param));

    if(argc == 3){
        strcpy(param_mqtt->url, argv[0]);
        strcpy(param_mqtt->username, argv[1]);
        strcpy(param_mqtt->password, argv[2]);
        app_set_mqtt_param(param_mqtt);
    }else
    if(argc == 0){
        app_get_mqtt_param(param_mqtt);
    }else{
        ESP_LOGE(TAG, "Invalid parameter");
        return ESP_ERR_INVALID_ARG;
    }

    free(param_mqtt);

    return ESP_OK;

}

static esp_err_t nvs_wifi_param_set(esp_periph_handle_t periph, int argc, char *argv[])
{
    //mqtt_nvs_param_t param_mqtt = NULL;
    wifi_config_t myConfig = {0};

    if(argc == 2){
        memcpy(myConfig.sta.ssid, argv[0], sizeof(myConfig.sta.ssid));
        memcpy(myConfig.sta.password, argv[1], sizeof(myConfig.sta.password));
        esp_wifi_disconnect();
        esp_wifi_set_config(WIFI_IF_STA, &myConfig);
        esp_wifi_connect();
    }else
    if(argc == 0){
        esp_wifi_get_config(WIFI_IF_STA, &myConfig);
        ESP_LOGI(TAG, "---current wifi config---");
        ESP_LOGI(TAG, "ssid:%s", myConfig.sta.ssid);
        ESP_LOGI(TAG, "password:%s", myConfig.sta.password);
        ESP_LOGI(TAG, "-------------------------");
    }else{
        ESP_LOGE(TAG, "Invalid parameter");
        return ESP_ERR_INVALID_ARG;
    }

    return ESP_OK;
}


const periph_console_cmd_t cli_cmd[] = {
    { .cmd = "demo",       .id = 1,  .help = "demo",                    .func = console_demo_func },
    {
        .cmd = "play",        .id = 2, .help = "Play music",               .func = cli_play
    },

    { .cmd = "pause",       .id = 3,  .help = "Pause",                    .func = cli_pause },
    { .cmd = "resume",      .id = 4,  .help = "Resume",                   .func = cli_resume },
    { .cmd = "stop",        .id = 5,  .help = "Stop player",              .func = cli_stop },
    { .cmd = "setvol",      .id = 6,  .help = "Set volume",               .func = cli_set_vol },
    { .cmd = "getvol",      .id = 7,  .help = "Get volume",               .func = cli_get_vol },

    { .cmd = "scan",        .id = 8, .help = "Scan sdcard music file, cmd: \"scan [path]\",e.g. \"scan /sdcard\"",             .func = playlist_sd_scan },
    { .cmd = "list",        .id = 9, .help = "Show scanned playlist",                                                          .func = playlist_sd_show },
    { .cmd = "next",        .id = 10, .help = "Next x file to play, cmd: \"next [step]\"",                                      .func = playlist_sd_next },
    { .cmd = "prev",        .id = 11, .help = "Previous x file to play, cmd: \"prev [step]\"",                                  .func = playlist_sd_prev },    
    { .cmd = "mqtt",        .id = 12, .help = "mqtt param set",   .func = nvs_mqtt_param_set }, 
    { .cmd = "wifi",        .id = 13, .help = "wifi param set",   .func = nvs_wifi_param_set }, 
};

uint8_t initialise_console(void)
{
    periph_console_cfg_t console_cfg = {
        .command_num = sizeof(cli_cmd) / sizeof(periph_console_cmd_t),
        .commands = cli_cmd,
        .buffer_size = 384,
    };
    esp_periph_handle_t console_handle = periph_console_init(&console_cfg);
    esp_periph_start(set, console_handle);
    return 0;
}